/*
 * command.c
 *
 *  Created on: 2010-12-28
 *      Author: root
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "command.h"
#ifdef __LINUX__
#include <netdb.h>
#endif




#define BUFSIZE 2048

/* 定义命令标示符 */
  unsigned int SHOW_TCP = 0X01;
  unsigned int SHOW_UDP = 0X02;
  unsigned int do_print = 0X03;
  unsigned int make_log = 0X04;
  unsigned int SHOW_ALL = 0X0F;
  unsigned int ids      = 0X05;


int do_command(unsigned int command)
{
  struct port port[1024];
  int size, n = 0;
  int listenfd;
  int logforce;


    const char *pathname = "./logtext.txt";
    u_char buf[BUFSIZE];

    /*PF_PACKET对底层数据进行抓取，SOCL_RAW原始ipv4,ipv6包，ETH_P_ALL指所有链路层上的包*/
     /*若是ETH_P_IP指所有IP包*/
    if ((listenfd = socket(PF_PACKET, SOCK_RAW,
          htons(ETH_P_ALL))) < 0)
	{
          perror("socket");
          exit(1);
    }

  if(command == SHOW_TCP) //show tpc ports information
  {
    size = get_port_list(port, 1024, TCP_PROTO);
    printf("protocol\t\tlocal_address\t\tremote_address\t\tstatus\n");
    while(n < size)
    {
      char * szRet = print(&(port[n]), 0, port[n].proto);
      printf("%s\n", szRet);
      ++n;
    }
  }
  else
  if(command == SHOW_UDP) //show udp ports information
  {
    size = get_port_list(port, 1024, UDP_PROTO);
    printf("protocol\t\tlocal_address\t\tremote_address\n");
    while(n < size)
    {
      char * szRet = print(&(port[n]), 0, port[n].proto);
      printf("%s\n", szRet);
      ++n;
    }

  }
  else
  if(command == SHOW_ALL) //show tcp and udp ports information
  {
    size = get_port_list(port, 1024, TCP_PROTO);
    while(n < size)
    {
       /*
       char * szRet = print(&(port[n++]), 0, port[n].proto);
       printf("%s\n", szRet);
       */
       /*for my beloved gril, we used another format of printf*/
        print(&(port[n]), 1, port[n].proto);
        ++n;
    }
    n = 0;
    size = get_port_list(port, 1024, UDP_PROTO);
    while(n < size)
    {
      char * szRet = print(&(port[n]), 0, port[n].proto);
      printf("%s\n", szRet);
      ++n;
    }

  }
  else
	  if(command == do_print) //print the packet information to command line
	  {
      	for (;;) //while(1)
      		{
      	          if ((n = recv(listenfd, buf, BUFSIZE, 0)) > 0)
      			{
      	                	hex_print(buf, n, 0);
      	                	decode_eth(buf);
      	        }

      	    }
	  }
   else
		if(command == make_log) //record the packet information to logtext.txt
		  {
			  if ((logforce = open(pathname,O_RDWR | O_CREAT | O_APPEND,0600)) == -1 )
			          	     {
			          	      perror("open()");
			          	      exit(-1);
			          	     }
			          	    memset(buf,0,sizeof(buf));
			          	    for (;;)
			          		{
			          	          if ((n = recv(listenfd, buf, BUFSIZE, 0)) > 0)
			          			{
			          	                	logtext(logforce, buf);
			          	        }

			          	    }
			          	    memset(buf,0,sizeof(buf));
			          	    close(logforce);
		  }
		else
			if(command == ids) //check the packets ----intrusion detection
			{

				printf("over");
				for(;;)
				{
					sbuffptr=malloc(sizeof(struct sbuff));
					if ((n = recv(listenfd, buff, BUFSIZE, 0)) > 0)
					{
						struct ethhdr *eth = (struct ethhdr *)buff;
						if(ntohs(eth->h_proto) == ETH_P_ARP)
						{
							//struct ether_arp *arph = (struct arphdr *)buff+sizeof(struct ethhdr);
							//sbuffptr->nh.arph=arph;
							process_arp(buff);
						}
						if(ntohs(eth->h_proto) == ETH_P_IP)
						{
							struct iphdr *iph = (struct iphdr *)(buff+sizeof(struct ethhdr));
							sbuffptr->nh.iph=iph;
							sbuffptr->data=(unsigned char*)buff;

							switch(iph->protocol){
							case 6: //log.tcppacket++;
							sbuffptr->h.tcph=(struct tcphdr *)&buff[iph->ihl<<2];
							sbuffptr->data=(unsigned char*)(buff+(iph->ihl*4)+(sbuffptr->h.tcph->doff<<2));
							process_tcp(sbuffptr);
						   break;

							case 17: //log.udppacket++;
							sbuffptr->h.udph=(struct udphdr *)&buff[iph->ihl<<2];
							sbuffptr->data=(unsigned char*)(buff+(iph->ihl*4)+8);
							process_udp(sbuffptr);
							break;

							case 1: //log.icmppacket++;
							sbuffptr->h.icmph=(struct icmphdr *)&buff[iph->ihl<<2];
							sbuffptr->data=(unsigned char*)(buff+(iph->ihl*4)+8);
							do_log("asdfasfderqtwe",sbuffptr);
							process_icmp(sbuffptr);
							break;

							case 2: //log.igmppacket++;
							sbuffptr->h.igmph=(struct igmphdr *)&buff[iph->ihl<<2];
							process_igmp(sbuffptr);
							break;

							default: //log.unknownpacket++;
							printf("Unkown Protocol:%d\n",iph->protocol);
							break;
								   }
						}
					}
				}
					free(sbuffptr);
	    	}else
  {
   fprintf(stderr, "UNKNOW COMMAND %d\n", command);
  }
  return 1;
}

